package cn.mastor.basic.service.impl;

import cn.mastor.basic.config.BussinessException;
import cn.mastor.basic.constant.BaseConstant;
import cn.mastor.basic.domain.AccountLogin;
import cn.mastor.basic.domain.WechatLoginDto;
import cn.mastor.basic.jwt.JwtUtils;
import cn.mastor.basic.jwt.RsaUtils;
import cn.mastor.basic.jwt.UserInfo;
import cn.mastor.basic.service.ILoginService;
import cn.mastor.basic.util.*;
import cn.mastor.system.domain.Menu;
import cn.mastor.system.mapper.MenuMapper;
import cn.mastor.system.mapper.PermissionMapper;
import cn.mastor.user.domain.Logininfo;
import cn.mastor.user.domain.User;
import cn.mastor.user.domain.Wxuser;
import cn.mastor.user.mapper.LogininfoMapper;
import cn.mastor.user.mapper.UserMapper;
import cn.mastor.user.mapper.WxuserMapper;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.security.PrivateKey;
import java.util.*;

@Service
public class LoginServiceImpl implements ILoginService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WxuserMapper wxuserMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Override
    public Map<String, Object> accountLogin(AccountLogin dto) {
        Logininfo logininfo = logininfoMapper.findByName(dto.getUsername(),dto.getType());
        if (null==logininfo){
            throw new BussinessException("账号不存在！");
        }
        String epwd = EncryptionUtil.encryption(dto.getPassword(), logininfo.getSalt());
//        System.out.println(epwd);
//        System.out.println(logininfo.getPassword());
        System.out.println(dto.getCode());
        if (null==dto.getCode()){
            if (!logininfo.getPassword().equals(epwd)){
            throw new BussinessException("密码1111错误！");
            }
        }
    if (dto.getCode()!=null){
        if (!dto.getCode().equalsIgnoreCase((String) redisTemplate.opsForValue().get(dto.getUsername()))){
            throw new BussinessException("验证码错误！");
        }
    }
        Map<String, Object> reUser = getReUser(logininfo);
        return reUser;
    }

    @Override
    public AjaxResult wechatLogin(WechatLoginDto dto) {
        if (StringUtils.isBlank(dto.getCode())){
            throw new BussinessException("参数不能为空！");
        }
        Pair<String, String> pair = this.getOpenidAndToken(dto.getCode());
        Wxuser wxuser = wxuserMapper.findByOpenId(pair.getRight());
        if (null!=wxuser && null!=wxuser.getUserId()){
            Logininfo logininfo = logininfoMapper.findByUserId(wxuser.getUserId());
            Map<String, Object> reUser = getReUser(logininfo);
            return AjaxResult.me().success(reUser);
        }else {
//            System.out.println("是否大大大大");
            StringBuffer sb = new StringBuffer()
                    .append("?accessToken=")
                    .append(pair.getLeft())
                    .append("&openId=").append(pair.getRight());
            return AjaxResult.me().fail("nobinder").setResultObj(sb);
        }
    }

    @Override
    public Map<String, Object> wechatBinder(WechatLoginDto dto) {
        System.out.println(redisTemplate.opsForValue().get(dto.getPhone()));
        System.out.println(dto.getVerifyCode());
        if(!dto.getVerifyCode().equalsIgnoreCase((String) redisTemplate.opsForValue().get(dto.getPhone()))){
            throw new BussinessException("验证码错误");
        }
        String url = String.format(BaseConstant.WxLoginCons.WX_LOGIN_USER_INFO,dto.getAccessToken(),
                dto.getOpenId());
        String s = HttpUtil.httpGet(url);
        Wxuser wxuser = JSONObject.parseObject(s, Wxuser.class);
        User user = userMapper.findByPhone(dto.getPhone());
//        System.out.println("找到的User"+user);
        Logininfo logininfo = new Logininfo();
        if (null==user){
            user = initUser(dto);
            System.out.println(user);
            BeanUtils.copyProperties(user,logininfo);
//            System.out.println("赋值后的loginfo"+logininfo);
            logininfo.setType(1);
            logininfoMapper.add(logininfo);
            Logininfo byName = logininfoMapper.findByName(logininfo.getUsername(), 1);
            user.setLogininfoId(byName.getId());
            userMapper.add(user);
        }else {
            System.out.println(user.getId());
            logininfo = logininfoMapper.findByUserId(user.getId());
            System.out.println("找到的logiinfo"+logininfo);
        }
        wxuser.setUserId(user.getId());
        wxuserMapper.add(wxuser);
        Map<String, Object> reUser = getReUser(logininfo);
        return reUser;
    }
    private User initUser(WechatLoginDto dto){
        // 盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 密码
        String password = salt + "1";
        String encryPwd = MD5Utils.encrypByMd5(password);
        User user = new User(dto.getPhone(), dto.getPhone(), "", salt, encryPwd, 1, 0, new Date(), "", null);
//        System.out.println(user);
        return user;
    }
    private Pair<String, String> getOpenidAndToken(String code) {
        String utl = String.format(BaseConstant.WxLoginCons.WX_LOGIN_TOKEN_URL, BaseConstant.WxLoginCons.WX_LOGIN_APPID, BaseConstant.WxLoginCons.WX_LOGIN_SECRET, code);
        String s = HttpUtil.httpGet(utl);
        JSONObject jsonObject = JSONObject.parseObject(s);
        String access_token = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");
        return Pair.of(access_token,openid);
    }
    private Map<String, Object> getReUser(Logininfo logininfo) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        PrivateKey privateKey = RsaUtils.getPrivateKey(JwtUtils.class.getClassLoader().getResource("jwt/pethome_auth_rsa.pri").getFile());
        UserInfo user = new UserInfo();
        user.setLogininfo(logininfo);
        if (0 == logininfo.getType()){
            List<String> permissions = permissionMapper.findByLogininfoId(logininfo.getId());
            List<Menu> menus = menuMapper.loadOwnMenuByLogininId(logininfo.getId());
            user.setPermissions(permissions);
            user.setMenus(menus);
                hashMap.put("permissions", permissions);
                hashMap.put("menus", menus);
            System.out.println(hashMap);
        }
        String token = JwtUtils.generateTokenExpireInMinutes(user, privateKey, 300);
        // 将logininfo敏感字段置空
        logininfo.setPassword("");
        logininfo.setSalt("");
        logininfo.setPhone("");
        // 返回给前端
        hashMap.put("token", token);
        hashMap.put("logininfo", logininfo);
        return hashMap;
    }

}
